package com.runa.rccprotocol.analysis;

import com.runa.monitor.comm.dto.newComm.HotMeterVO;
import com.runa.protocol.analysis.MetaBufferAnalysis;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.analysis.En13757.HeadInfo;
import com.runa.rccprotocol.analysis.En13757.UnitData;
import com.runa.rccprotocol.analysis.En13757.decoder.DIF;
import com.runa.rccprotocol.analysis.En13757.decoder.DefaultEnDecoder;
import com.runa.rccprotocol.analysis.En13757.decoder.VIF;
import com.runa.rccprotocol.dto.equdata.TerminalCalendarClock;
import com.runa.rccprotocol.dto.runa.RunaConcenAffirmDeny;
import com.runa.rccprotocol.dto.runa.RunaConcenResponseData;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static com.runa.rccprotocol.analysis.RunaDeviceAnalysis.*;
import static com.runa.rccprotocol.analysis.RunaEquDataAnalysis.heatMeterFaults;

/**
 * @author diandian
 * @Date 2021/12/16 14:34
 */
public class EnAnalysis extends MetaBufferAnalysis<byte[]> {

    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public int fill(byte[] data, int length, String netEquNo) {
        int begin;
        for (begin = 0; begin < length; begin++) {
            if ((data[begin] & 0xff) == 0x68) {
                break;
            }
        }
        int deviceType = data[begin + 1] & 0xff;
        switch (deviceType) {
            case 0x25:
            case 0x20:
                heatMeterData(begin + 2, data);
                return 0;
            default:
        }
        if (0xE5 == (data[0] & 0xff) || 0x00 == (data[0] & 0xff)) {
            this.responseData = new RunaConcenAffirmDeny(true);
            return length - 1;
        }
        DefaultEnDecoder defaultEnDecoder = new DefaultEnDecoder();
        defaultEnDecoder.init(data, length);
        int check = defaultEnDecoder.check();
        if (check != 0) {
            return check;
        }
        HeadInfo headInfo = defaultEnDecoder.getHeadInfo();
        List<UnitData> unitData = defaultEnDecoder.getUnitData(headInfo.getDataLength(), headInfo.getHeadEndIndex());
        HotMeterVO meterData = new HotMeterVO();
        meterData.setMeterSerial(headInfo.getSerialNo());
        for (UnitData unitDatum : unitData) {
            if (unitDatum.getDif().getDif_type() == DIF.DIF_Type.fault) continue;
            VIF.VIF_Type dataType = unitDatum.getVif().getDataType();
            Object value = unitDatum.getValue();
            if (dataType == null) {
                continue;
            }
            //因为欧标里面会出现两个相同的值，所以现在就按照规定：取值第一个不是0的数据
            System.out.println("FFFFF");
            switch (dataType) {
                case inTem:
                    if (meterData.getSupplyTemp() == null || meterData.getSupplyTemp() == 0) {
                        meterData.setSupplyTemp(((Double) value).floatValue());
                    }
                    break;
                case outTem:
                    if (meterData.getReturnTemp() == null || meterData.getReturnTemp() == 0) {
                        meterData.setReturnTemp(((Double) value).floatValue());
                    }
                    break;
                case accHeat:
                    if (meterData.getAccHeat() == null || meterData.getAccHeat() == 0) {
                        meterData.setAccHeat(((Double) value).floatValue() / 1000);
                    }
                    break;
                case power:
                    if (meterData.getPower() == null || meterData.getPower() == 0) {
                        meterData.setPower(((Double) value).floatValue() / 1000);
                    }
                    break;
                case flow:
                    if (meterData.getFlow() == null || meterData.getFlow() == 0) {
                        meterData.setFlow(((Double) value).floatValue());
                    }
                    break;
                case accFlow:
                    if (meterData.getAccFlow() == null || meterData.getAccFlow() == 0) {
                        meterData.setAccFlow(((Double) value).floatValue());
                    }
                    break;
                case date_f:
//                    TerminalCalendarClock meterDate = meterData.getMeterDate();
                    Date meterDate = meterData.getMeterDate();
                    if (meterDate == null || (value != null && meterDate.compareTo((Date) value) < 0)) {
                        meterData.setMeterDate((Date) value);
                    }
                    break;
            }
        }
        RunaConcenResponseData responseData = new RunaConcenResponseData();
        if (meterData.getReadDate() == null) meterData.setReadDate(new Date());
        responseData.addRepData(meterData);
        this.responseData = responseData;

        int currentIndex = defaultEnDecoder.getCurrentIndex();

        //尾巴 2个字节 下标是从0开始，占一个长度。
//        return length - currentIndex - 2 - 1;
        return 0;
    }

    private void heatMeterData(int idx, byte[] bytes) {
        RunaConcenResponseData responseData = new RunaConcenResponseData();
        HotMeterVO meter = new HotMeterVO();
        String addr = ByteUtil.byteToHexStringFlip(bytes, idx, 4);
        meter.setMeterSerial(addr);
        idx += 7;
        int ctrl = bytes[idx++] & 0xff;
        int len = bytes[idx++] & 0xff;
        String functionCode = ByteUtil.byteToHexStringFlip(bytes, idx, 3);
        idx += 3;
        boolean tianJinWanHua = functionCode.equals("0052C3");
        if (ctrl == 0x81 || (ctrl == 0xC1 && tianJinWanHua)) {
            //天津万华
            if (tianJinWanHua) {
                parseTianJinWanHua(idx, bytes, len, meter);
                //                parseTianJinWanHua(idx, bytes,meter);
                return;
            }
            float accCold = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
            idx += 4;
//            meter.setSettDateHeatColdVal();
            float v = toKwh(accCold, bytes[idx++] & 0xff);
            float accHeat = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
            idx += 4;
            meter.setAccHeat(toKwh(accHeat, bytes[idx++] & 0xff));
            float power = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
            idx += 4;
            meter.setPower(toKw(power, bytes[idx++] & 0xff));
            float flow = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.0001);
            idx += 4;
            meter.setFlow(toM3h(flow, bytes[idx++] & 0xff));
            float accFlow = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
            idx += 4;
            meter.setAccFlow(toM3(accFlow, bytes[idx++]));
            meter.setSupplyTemp((float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 3)) * 0.01));
            idx += 3;
            meter.setReturnTemp((float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 3)) * 0.01));
            idx += 3;
            meter.setWorkTime(Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 3)));
            idx += 3;
            meter.setMeterDate(TerminalCalendarClock.getInstance(bytes, idx).toDate());
            idx += 7;
            meter.setStatus(ByteUtil.byteToHexString(bytes, idx, 2));
            if ("FFFF".equals(meter.getStatus())) {
                meter.setSuccess(false);
            } else {
                meter.setFaultCode(heatMeterFaults(meter.getStatus()));
            }
            meter.setReadDate(new Date());
            responseData.addRepData(meter);
            this.responseData = responseData;
        } else {
            this.responseData = new RunaConcenAffirmDeny(false);
        }
    }

    private void parseTianJinWanHua(int idx, byte[] bytes, int size, HotMeterVO meter) {
        int index = idx;
        for (; index < size + idx - 1; index++) {
            bytes[index] = (byte) ((bytes[index] & 0xff) - 0x33);
        }
        byte unit = bytes[idx++];
        float accCold = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
        idx += 4;
//        meter.setSettDateHeatColdVal(toKwh(accCold, unit & 0xff));
        unit = bytes[idx++];
        float accHeat = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
        idx += 4;
        meter.setAccHeat(toKwh(accHeat, unit & 0xff));
        unit = bytes[idx++];
        float power = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
        idx += 4;
        meter.setPower(toKw(power, unit & 0xff));
        unit = bytes[idx++];
        float flow = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.0001);
        idx += 4;
        meter.setFlow(toM3h(flow, unit & 0xff));
        unit = bytes[idx++];
        float accFlow = (float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 4)) * 0.01);
        idx += 4;
        meter.setAccFlow(toM3(accFlow, unit));
        meter.setSupplyTemp((float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 3)) * 0.01));
        idx += 3;
        meter.setReturnTemp((float) (Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 3)) * 0.01));
        idx += 3;
        meter.setWorkTime(Integer.parseInt(ByteUtil.byteToHexStringFlip(bytes, idx, 3)));
        idx += 3;
        meter.setMeterDate(TerminalCalendarClock.getInstance(bytes, idx).toDate());
        idx += 7;
        meter.setStatus(ByteUtil.byteToHexString(bytes, idx, 2));
        if ("FFFF".equals(meter.getStatus())) {
            meter.setSuccess(false);
        } else {
            meter.setFaultCode(heatMeterFaults(meter.getStatus()));
        }
        meter.setReadDate(new Date());

    }

    public static void main(String[] args) {
//        String s="7B0900623034383730323034000000684C4C6808587288346842A511410C1A7000000C06000000000C14000000003C2BBDEBDDDD3B3BBDEBDD0A5A07030A5E06030A6200000A278328046D1911C9284C06000000004C1400000000426CDF25D2167B";
//        String s="7B0900623034383730323034000000684C4C68080E7214846042A511410CD00000000C06020000000C14277600000C2B000000000B3B0000000A5A91010A5E14020A6222F00A277731046D2D0FF6224C06010000004C1472530000426CDF259D167B";
//        String s="7B0900113034383730323034000000E57B  ";
//        String s = "7B0900DE303438373036333800000068C8C86808007275599966A7320304A85000000974080970080C06478004000C14068755010B2D0000000B3B0000000A5B00000A5F00000A6200004C14068755014C06478004000C78755999660C22118809003C22860904007C2237400300426C01018C010647800400CC0106478004008C020647800400CC0206478004008C030647800400CC0306478004008C040647800400CC0406478004008C050647800400CC0506478004008C060647800400CC0606478004008C070647800400CC0706478004008C0806478004006A167B      ";
//        String s = "7B0900B8303438373032323000000068A4A4680800727684204224232E0CF93000000C05570808018C1005000000008C20050000000006093F2306440C2A621905000B3A0662000A5A04040A5E32030A6272000B26357510046D240CF92C4C05462906014C1291197441CC100500000000CC200500000000C2362A42EC7E1E3A8C0105632806018C0112866550418C1105000000008C21050000000041E00A9D8201EC7E01378C4014300000008C8040143000000087167B        ";
//        String s = "7B0900DE303438373032323000000068C8C86808007277767467A73203049C0000000974080970080C06523806000C14224399000B2D4100000B3B5605000A5B40000A5F34000A6264004C14925796004C06501906000C78777674670C22548608003C22225200007C2222520000426C01018C010650190600CC0106719205008C020694800500CC0206948005008C030694800500CC0306948005008C040694800500CC0406948005008C050694800500CC0506948005008C060622780500CC0606045805008C070611300500CC0706690405008C080680910400DA167B                ";

        //42208476
//        String s ="7B0900BA303438373032323000000068A4A4680800727684204224232E0C68B000000C05479108018C1005000000008C2005000000001C12175602450C2A000000000B3A0000000A5A12020A5E76020A6264F00B26868110046D320F15314C05462906014C1291197441CC100500000000CC200500000000426CFE2A42EC7E1E3A8C0105632806018C0112866550418C1105000000008C21050000000082016CE1278201EC7E01378C4014300000008C80401430000000D3167B                  ";
        String s ="7B0900113034383730323230000000E57B                        ";
//        String s ="7B0900B7303438373032323000000068A4A4680800727684204224232E0C73B000000C05479108018C1005000000008C2005000000000C093125450C2A000000000B3A0000000A5A92010A5E69020A6277F00B26128210046D0C1116314C05462906014C1291197441CC100500000000CC200500000000217E2A42EC7E1E3A8C0105632806018C0112866550418C1105000000008C2105000000008660E1278201EC7E01378C4014300000008C80401430000000CD167B                    ";

//        String s = "7B0900DE303438373032323000000068C8C86808007277767467A73203041F0000000974080970080C06971206000C14926695000B2D4500000B3B5205000A5B41000A5F34000A6271004C14028382004C06113005000C78777674670C22827908003C22225200007C2246310000426C01018C010671920500CC0106948005008C020694800500CC0206948005008C030694800500CC0306948005008C040694800500CC0406948005008C050694800500CC0506227805008C060604580500CC0606113005008C070669040500CC0706809104008C08068091040042167B          ";
//        String s = "7B0900B4303438373032323000000068A4A4680800726984204224232E0CE13000000C05537888008C1005000000000E560000008B64C5E98D2A705805000B3A4287000A5A03040A5E47030A6256000B26347510046D270BF92C4C05541484004C1263944648CC100500000000CC20050000000021362A42EC7E1E3A8C0105281284008C0112104199478C1105000000008C21050000000055E085278201EC7E01378C4014300000008C80401420000000BF167B        ";

//        String s="7B 09 00 58 30 34 38 37 30 32 30 34 00 00 00  FE FE FE FE FE FE FE FE FE FE FE FE FE 68 25 99 15 46 11 00 4D 22 81 2E 1F 90 00 00 00 00 00 05 84 83 08 01 05 61 02 00 00 17 16 69 00 00 35 30 71 15 00 2C 77 32 00 46 29 00 93 99 01 38 19 10 22 02 23 20 00 00 96 16  7B";
        byte[] bytes = ByteUtil.hexStringToByte(s);
        EnAnalysis enAnalysis = new EnAnalysis();
        DtuHDBufferAnalysis dtuHDBufferAnalysis = new DtuHDBufferAnalysis(enAnalysis);
        dtuHDBufferAnalysis.fill(bytes, bytes.length, "");
    }
}